package pl.edu.agh.gui;

import static pl.edu.agh.Values.maxPeople;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;
import org.jfree.chart.JFreeChart;
import org.jfree.ui.RefineryUtilities;

import pl.edu.agh.Agent;
import pl.edu.agh.ChartDemo;
import pl.edu.agh.ElFaroChartFactory;
import pl.edu.agh.HowCountStrategies;
import pl.edu.agh.IStrategy;
import pl.edu.agh.MainLogic;
import pl.edu.agh.strategies.DifferentFromLastWeek;
import pl.edu.agh.strategies.Random;
import pl.edu.agh.strategies.SameAsLastWeek;
import pl.edu.agh.strategies.WeekAverage;
import pl.edu.agh.strategies.WeekDayAverage;
import pl.edu.agh.strategies.WeekTrend;

//VS4E -- DO NOT REMOVE THIS LINE!
public class MainWindow extends JFrame {

	private static final String MEAN = "mean";
	private static final String BEST = "best";
	private static final String ALL = "all";
	private static final long serialVersionUID = 1L;
	private JButton nextStepButton;
	private JTextField nrOfStepsTextField;
	private JButton stepsButton;
	private JCheckBox sameAsLastWeekCheckBox1;
	private JCheckBox weekAverageCheckBox2;
	private JCheckBox weekDayAverageCheckBox3;
	private JCheckBox weekTrendCheckBox4;
	private JButton createAgentsButton;
	private JLabel jLabel0;
	private JTextField jTextField1;
	private JLabel jLabel1;
	private JLabel resultsLabel;
	private boolean initialized;
	private JCheckBox randomCheckBox0;
	private ArrayList<Agent> agents;
	private ArrayList<Integer> history;
	private MainLogic mainLogic;
	private HowCountStrategies howCount = HowCountStrategies.ALL;
	private ArrayList<Class<? extends IStrategy>> strategies;
	private JCheckBox differentFromLastWeekCheckBox;
	private JPanel jPanel0;
	private JLabel jLabel3;
	private JComboBox jComboBox0;
	ElFaroChartFactory factory = new ElFaroChartFactory();
	ChartDemo demo;
	boolean fakeVersion = false;
	
	private JCheckBox fakeVersionCheckBox;
	private static final String PREFERRED_LOOK_AND_FEEL = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
	public MainWindow() {
		initComponents();
	}

	private void initComponents() {
		setLayout(new GroupLayout());
		add(getNextStepButton(), new Constraints(new Leading(12, 12, 12), new Leading(354, 10, 10)));
		add(getNrOfStepsTextField(), new Constraints(new Leading(119, 62, 10, 10), new Leading(355, 12, 12)));
		add(getStepsButton(), new Constraints(new Leading(187, 12, 12), new Leading(354, 12, 12)));
		add(getJCheckBox0(), new Constraints(new Leading(12, 8, 8), new Leading(89, 10, 10)));
		add(getJCheckBox1(), new Constraints(new Leading(12, 8, 8), new Leading(112, 8, 8)));
		add(getJLabel0(), new Constraints(new Leading(12, 12, 12), new Leading(70, 10, 10)));
		add(getJLabel1(), new Constraints(new Leading(296, 250, 10, 10), new Leading(375, -17, 10, 10)));
		add(getJButton2(), new Constraints(new Leading(12, 12, 12), new Leading(325, 12, 12)));
		add(getJCheckBox5(), new Constraints(new Leading(12, 8, 8), new Leading(135, 8, 8)));
		add(getJCheckBox2(), new Constraints(new Leading(12, 8, 8), new Leading(158, 8, 8)));
		add(getJCheckBox3(), new Constraints(new Leading(12, 8, 8), new Leading(181, 8, 8)));
		add(getJCheckBox4(), new Constraints(new Leading(12, 8, 8), new Leading(204, 8, 8)));
		add(getJPanel0(), new Constraints(new Leading(272, 327, 10, 10), new Leading(47, 225, 10, 10)));
		add(getJLabel2(), new Constraints(new Leading(260, 164, 10, 10), new Leading(358, 12, 12)));
		add(getJLabel3(), new Constraints(new Leading(12, 10, 10), new Leading(229, 11, 11)));
		add(getJComboBox0(), new Constraints(new Leading(12, 10, 10), new Leading(249, 11, 11)));
		add(getJCheckBox6(), new Constraints(new Leading(14, 10, 10), new Leading(283, 10, 10)));
		setSize(609, 394);
	}

	private JCheckBox getJCheckBox6() {
		if (fakeVersionCheckBox == null) {
			fakeVersionCheckBox = new JCheckBox();
			fakeVersionCheckBox.setText("fake version");
		}
		return fakeVersionCheckBox;
	}

	private JComboBox getJComboBox0() {
		if (jComboBox0 == null) {
			jComboBox0 = new JComboBox();
			jComboBox0.setModel(new DefaultComboBoxModel(new Object[] { ALL, MEAN, BEST }));
		}
		return jComboBox0;
	}

	private JLabel getJLabel3() {
		if (jLabel3 == null) {
			jLabel3 = new JLabel();
			jLabel3.setText("How count:");
		}
		return jLabel3;
	}

	private JPanel getJPanel0() {
		if (jPanel0 == null) {
			jPanel0 = new JPanel();
			jPanel0.setLayout(new GroupLayout());
		}
		return jPanel0;
	}

	private JCheckBox getJCheckBox5() {
		if (differentFromLastWeekCheckBox == null) {
			differentFromLastWeekCheckBox = new JCheckBox();
			differentFromLastWeekCheckBox.setSelected(true);
			differentFromLastWeekCheckBox.setText("Different from last week");
		}
		return differentFromLastWeekCheckBox;
	}

	private JLabel getJLabel2() {
		if (resultsLabel == null) {
			resultsLabel = new JLabel();
			resultsLabel.setText("result: ");
		}
		return resultsLabel;
	}

	private JLabel getJLabel1() {
		if (jLabel1 == null) {
			jLabel1 = new JLabel();
		}
		return jLabel1;
	}

	private JTextField getJTextField1() {
		if (jTextField1 == null) {
			jTextField1 = new JTextField();
			jTextField1.setText("100");
		}
		return jTextField1;
	}

	private JLabel getJLabel0() {
		if (jLabel0 == null) {
			jLabel0 = new JLabel();
			jLabel0.setText("Choose strategies:");
		}
		return jLabel0;
	}

	private JButton getJButton2() {
		if (createAgentsButton == null) {
			createAgentsButton = new JButton();
			createAgentsButton.setText("Create agents");
			createAgentsButton.addMouseListener(new MouseAdapter() {

				public void mouseClicked(MouseEvent event) {
					jButton2MouseMouseClicked(event);
				}
			});
		}
		return createAgentsButton;
	}

	private JCheckBox getJCheckBox4() {
		if (weekTrendCheckBox4 == null) {
			weekTrendCheckBox4 = new JCheckBox();
			weekTrendCheckBox4.setSelected(true);
			weekTrendCheckBox4.setText("Week trend");
		}
		return weekTrendCheckBox4;
	}

	private JCheckBox getJCheckBox3() {
		if (weekDayAverageCheckBox3 == null) {
			weekDayAverageCheckBox3 = new JCheckBox();
			weekDayAverageCheckBox3.setSelected(true);
			weekDayAverageCheckBox3.setText("Week/Day average");
		}
		return weekDayAverageCheckBox3;
	}

	private JCheckBox getJCheckBox2() {
		if (weekAverageCheckBox2 == null) {
			weekAverageCheckBox2 = new JCheckBox();
			weekAverageCheckBox2.setSelected(true);
			weekAverageCheckBox2.setText("Week average");
		}
		return weekAverageCheckBox2;
	}

	private JCheckBox getJCheckBox1() {
		if (sameAsLastWeekCheckBox1 == null) {
			sameAsLastWeekCheckBox1 = new JCheckBox();
			sameAsLastWeekCheckBox1.setSelected(true);
			sameAsLastWeekCheckBox1.setText("Same as last week");
		}
		return sameAsLastWeekCheckBox1;
	}

	private JCheckBox getJCheckBox0() {
		if (randomCheckBox0 == null) {
			randomCheckBox0 = new JCheckBox();
			randomCheckBox0.setSelected(true);
			randomCheckBox0.setText("Random Strategy");
		}
		return randomCheckBox0;
	}

	private JButton getStepsButton() {
		if (stepsButton == null) {
			stepsButton = new JButton();
			stepsButton.setText("Steps");
			stepsButton.setEnabled(false);
			stepsButton.addMouseListener(new MouseAdapter() {

				public void mouseClicked(MouseEvent event) {
					stepsButtonMouseMouseClicked(event);
				}
			});
		}
		return stepsButton;
	}

	private JTextField getNrOfStepsTextField() {
		if (nrOfStepsTextField == null) {
			nrOfStepsTextField = new JTextField();
			nrOfStepsTextField.setText("10");
			nrOfStepsTextField.setEnabled(false);
		}
		return nrOfStepsTextField;
	}

	private JButton getNextStepButton() {
		if (nextStepButton == null) {
			nextStepButton = new JButton();
			nextStepButton.setText("Next step");
			nextStepButton.setEnabled(false);
			nextStepButton.addMouseListener(new MouseAdapter() {

				public void mouseClicked(MouseEvent event) {
					nextStepButtonMouseMouseClicked(event);
				}
			});
		}
		return nextStepButton;
	}

	private static void installLnF() {
		try {
			String lnfClassname = PREFERRED_LOOK_AND_FEEL;
			if (lnfClassname == null)
				lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
			UIManager.setLookAndFeel(lnfClassname);
		} catch (Exception e) {
			System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
					+ " on this platform:" + e.getMessage());
		}
	}

	/**
	 * Main entry of the class. Note: This class is only created so that you can
	 * easily preview the result at runtime. It is not expected to be managed by
	 * the designer. You can modify it as you like.
	 */
	public static void main(String[] args) {
		installLnF();
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				MainWindow frame = new MainWindow();
				frame.setDefaultCloseOperation(MainWindow.EXIT_ON_CLOSE);
				frame.setTitle("MainWindow");
				frame.getContentPane().setPreferredSize(frame.getSize());
				frame.pack();
				frame.setLocationRelativeTo(null);
				frame.setVisible(true);
			}
		});
	}

	private void jButton2MouseMouseClicked(MouseEvent event) {

		this.strategies = new ArrayList<Class<? extends IStrategy>>();
		
		String howCountString = (String) jComboBox0.getSelectedItem();
		if(ALL.equals(howCountString))
		{
			howCount = HowCountStrategies.ALL;
		}
		else if(BEST.equals(howCountString))
		{
			howCount = HowCountStrategies.BEST;
		}
		else if(MEAN.equals(howCountString))
		{
			howCount = HowCountStrategies.MEAN;
		}
		
		if (sameAsLastWeekCheckBox1.isSelected())
			strategies.add(SameAsLastWeek.class);
		if (randomCheckBox0.isSelected())
			strategies.add(Random.class);
		if (weekAverageCheckBox2.isSelected())
			strategies.add(WeekAverage.class);
		if (weekDayAverageCheckBox3.isSelected())
			strategies.add(WeekDayAverage.class);
		if (weekTrendCheckBox4.isSelected())
			strategies.add(WeekTrend.class);
		if (differentFromLastWeekCheckBox.isSelected())
			strategies.add(DifferentFromLastWeek.class);

		if(fakeVersionCheckBox.isSelected())
		{
			fakeVersion = true;
			System.out.println("fake version enabled");
		}
		else
		{
			fakeVersion = false;
			System.out.println("fake version disabled");
		}
		
		if (strategies.size() > 0) {

			this.agents = new ArrayList<Agent>();
			this.history = new ArrayList<Integer>();

			history.add(45);
			history.add(32);
			history.add(12);
			history.add(25);
			history.add(21);
			history.add(38);
			history.add(11);
			history.add(32);
			history.add(43);

			for (int i = 0; i < maxPeople; i++) {
				Agent bond = new Agent(history, strategies, howCount);
				agents.add(bond);
			}

			this.initialized = true;
			nrOfStepsTextField.setEnabled(true);
			nextStepButton.setEnabled(true);
			stepsButton.setEnabled(true);
			this.pack();

			mainLogic = new MainLogic();

		} else {
			this.initialized = false;
			nrOfStepsTextField.setEnabled(false);
			nextStepButton.setEnabled(false);
			stepsButton.setEnabled(false);
			this.pack();

			JOptionPane.showMessageDialog(null,
					"zaznacz przynajmniej jedna strategiee");
		}

	}

	private void nextStepButtonMouseMouseClicked(MouseEvent event) {
		if (this.initialized) {
			int went;
			went = MainLogic.step(agents, fakeVersion);
			history.add(went);
			resultsLabel.setText(went + " went.");
			System.out.println(history.toArray());
			if(fakeVersion)System.out.println("fake" + Arrays.toString(agents.get(0).getHistory().toArray()));
			if(demo != null) demo.dispose();
			JFreeChart chart = factory.createChart(history);
	        demo = new ChartDemo("historia", chart);
	        demo.pack();
	        
	        RefineryUtilities.centerFrameOnScreen(demo);
	        demo.setVisible(true);
		}
	}

	private void stepsButtonMouseMouseClicked(MouseEvent event) {
		try {
			StringBuilder output = new StringBuilder();
			int amount = Integer.parseInt(nrOfStepsTextField.getText());
			if(amount<=0) throw new Exception();
			int went;
			if (this.initialized) {
				for (int i = 0; i < amount; i++) {
					went = MainLogic.step(agents, fakeVersion);
					history.add(went);
					output.append(went + "");
					output.append(",");
					System.out.println(Arrays.toString(history.toArray()));
					if(fakeVersion)System.out.println("fake" + Arrays.toString(agents.get(0).getHistory().toArray()));
				}
			}
			resultsLabel.setText(output.toString());
			
			if(demo != null) demo.dispose();
	        demo = new ChartDemo("historia", factory.createChart(history));
	        demo.pack();
	        demo.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
	        RefineryUtilities.centerFrameOnScreen(demo);
	        demo.setVisible(true);
		} catch (Exception ex) {
			JOptionPane.showMessageDialog(null, "podaj poprawna ilosc krokow!");
		}
	}

}
